package lion.framework.core.task.rule;

import java.util.Arrays;

import lion.dev.web.Validator;
import lion.json.Json;

/**
 * Cron表达式中的一段 完整的Cron表达式有7段，每段有具体的时间限定
 * 
 * @author lion
 * @email hl_0074@sina.com
 * @date 2016年3月18日
 */
public class CronPos {

	public static final int TYPE_EVERY = 0;
	public static final int TYPE_RANGE = 1;
	public static final int TYPE_LIST = 2;
	public static final int TYPE_INTERVAL = 3;
	public static final int TYPE_RANGE_INTERVAL = 4;
	public static final int TYPE_NONSENS = 5;
	public static final int TYPE_VALUE = 6;

	public static final int TYPE_L = 7;
	public static final int TYPE_LW = 8;
	public static final int TYPE_W = 9;
	public static final int TYPE_SHARP = 10;

	private String expression;
	private int type = TYPE_EVERY;
	private int start;
	private int end;
	private int interval;
	private int[] vals;
	private int value;
	private int dow;
	private int wom;

	public CronPos(String expression) {

		this.expression = expression;
		if (this.expression.indexOf(",") > 0) {
			type = TYPE_LIST;
			vals = Validator.toIntArray(expression, ",");
			Arrays.sort(vals);
		} else if ("?".equals(expression)) {
			type = TYPE_NONSENS;
		} else if (expression.indexOf("/") > 0 && expression.indexOf("-") < 0) {
			type = TYPE_INTERVAL;

			String[] arr = expression.split("/");
			this.start = Validator.toInt(arr[0], 0);
			this.interval = Validator.toInt(arr[1], 1);
		} else if (expression.indexOf("/") < 0 && expression.indexOf("-") > 0) {
			type = TYPE_RANGE;

			String[] arr = expression.split("-");
			this.start = Validator.toInt(arr[0], 0);
			this.end = Validator.toInt(arr[1], 0);
		} else if (expression.indexOf("/") > 0 && expression.indexOf("-") > 0) {
			type = TYPE_RANGE_INTERVAL;
			String[] arr = expression.split("/");
			this.interval = Validator.toInt(arr[1], 1);

			arr = arr[0].split("-");
			this.start = Validator.toInt(arr[0], 0);
			this.end = Validator.toInt(arr[1], 0);
		} else if ("*".equals(expression)) {
			type = TYPE_EVERY;
		} else if ("L".equalsIgnoreCase(expression)) {
			type = TYPE_L;
			this.value = Validator.toInt(expression.substring(0, expression.length() - 1), 0);
		} else if ("LW".equalsIgnoreCase(expression)) {
			type = TYPE_LW;
		} else if (expression.endsWith("w") || expression.endsWith("W")) {
			type = TYPE_W;
			this.value = Validator.toInt(expression.substring(0, expression.length() - 1), 0);
		} else if (expression.indexOf("#") > 0) {
			type = TYPE_SHARP;
			String[] arr = expression.split("#");
			this.dow = Validator.toInt(arr[0], 1);
			this.wom = Validator.toInt(arr[1], 1);
		} else {
			type = TYPE_VALUE;
			this.value = Validator.toInt(expression, -1);
		}
	}

	public boolean match(int val) {

		switch (type) {
		case TYPE_EVERY:
		case TYPE_NONSENS:
			return true;
		case TYPE_RANGE:
			return val >= start && val <= end;
		case TYPE_LIST:
			return Arrays.binarySearch(vals, val) >= 0;
		case TYPE_VALUE:
			return val == value;
		case TYPE_INTERVAL:
			return val % interval == 0;
		case TYPE_RANGE_INTERVAL:
			return (val >= start && val <= end) && (val - start) % interval == 0;
		}
		return false;
	}

	public String getExpression() {

		return this.expression;
	}

	public int getType() {

		return type;
	}

	public int getStart() {

		return start;
	}

	public int getEnd() {

		return end;
	}

	public int getInterval() {

		return interval;
	}

	public int[] getVals() {

		return vals;
	}

	public int getValue() {

		return value;
	}

	public int getDow() {

		return dow;
	}

	public int getWom() {

		return wom;
	}

	@Override
	public String toString() {

		return Json.toJson(this);
	}

}
